﻿/*----------------------------------------------------------------------------------------
*
*  Copyright 2019, Gao Hai Hui, <fromzeropoint@126.com>.  All rights reserved.
*  https://gitee.com/helloworldghh/xoskit.git
*  Use of this source code is governed by a MIT license
*  that can be found in the License file.
*
----------------------------------------------------------------------------------------*/
#ifndef __XOSKIT_XOS_CORE_XOS_STL_SRC_PROTOCOL_PACKER_PROTOCOL_DAT_H__
#define __XOSKIT_XOS_CORE_XOS_STL_SRC_PROTOCOL_PACKER_PROTOCOL_DAT_H__

#include "../base/base.h"

namespace xos_protocol
{

    template< class T >
    class protocol_data : public xos_protocol::base
    {
    public:
        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        // 
        protocol_data( xos_box::i_serial * pSerial, xos_box::i_buf * pBuf ) :
            base( pSerial, pBuf )
        {
        }
        ~protocol_data()
        {
        }
    public:
        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        // 
        int un_pack( int nIndex, T * pT )
        {
            int ret = 0;
            switch( nIndex )
            {
            case T::MEMS:
                {
                    ret = un_pack_mem_array( T::MEM_SIZE, (char*)pT->mems, pT->n_mem_len, T::ARRAY_SIZE, &pT->n_mems, 0 );
                }
                break;
            case T::STRS:
                {
                    ret = un_pack_str_array( T::STR_SIZE, (char*)pT->strs, T::ARRAY_SIZE, &pT->n_strs, 0 );
                }
                break;
            case T::U64:
                {
                    ret = un_pack_int64_array( pT->u64, T::ARRAY_SIZE, &pT->n_u64, 0 );
                }
                break;
            case T::U32:
                {
                    ret = un_pack_int32_array( pT->u32, T::ARRAY_SIZE, &pT->n_u32, 0 );
                }
                break;
            case T::U16:
                {
                    ret = un_pack_int16_array( pT->u16, T::ARRAY_SIZE, &pT->n_u16, 0 );
                }
                break;
            case T::U8:
                {
                    ret = un_pack_int8_array( pT->u8, T::ARRAY_SIZE, &pT->n_u8, 0 );
                }
                break;
            case T::DOUBLE:
                {
                    ret = un_pack_double_array( pT->d, T::ARRAY_SIZE, &pT->n_d, 0 );
                }
                break;
            case T::FLOAT:
                {
                    ret = un_pack_float_array( pT->f, T::ARRAY_SIZE, &pT->n_f, 0 );
                }
                break;
            default:
                {
                    ret = 1;
                }
                break;
            }
            return ret;
        }
        int pack( int nIndex, T * pT )
        {
            int ret = 0;
            switch( nIndex )
            {
            case T::MEMS:
                {
                    ret = pack_mem_array( T::MEM_SIZE, (char*)pT->mems, pT->n_mem_len, pT->n_mems );
                }
                break;
            case T::STRS:
                {
                    ret = pack_str_array( T::STR_SIZE, (char*)pT->strs, pT->n_strs );
                }
                break;
            case T::U64:
                {
                    ret = pack_int64_array( pT->u64, pT->n_u64 );
                }
                break;
            case T::U32:
                {
                    ret = pack_int32_array( pT->u32, pT->n_u32 );
                }
                break;
            case T::U16:
                {
                    ret = pack_int16_array( pT->u16, pT->n_u16 );
                }
                break;
            case T::U8:
                {
                    ret = pack_int8_array( pT->u8, pT->n_u8 );
                }
                break;
            case T::DOUBLE:
                {
                    ret = pack_double_array( pT->d, pT->n_d );
                }
                break;
            case T::FLOAT:
                {
                    ret = pack_float_array( pT->f, pT->n_f );
                }
                break;
            default:
                {
                    ret = 1;
                }
                break;
            }
            return ret;
        }
        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        // 
        int set( int nIndex, T * pIn, T * pOut, xos::i_crt * pCrt )
        {
            int ret = 0;
            switch( nIndex )
            {
            case T::MEMS:
                {
                    for( xos::xos_u8 i = 0; i < pOut->n_mems; ++i )
                    {
                        pCrt->memcpy( pIn->mems[i], pOut->mems[i], pOut->n_mem_len[i] );
                        pIn->n_mem_len[i] = pOut->n_mem_len[i];
                    }
                    pIn->n_mems = pOut->n_mems;
                }
                break;
            case T::STRS:
                {
                    for( xos::xos_u8 i = 0; i < pOut->n_strs; ++i )
                    {
                        pCrt->strcpy( pIn->strs[i], pOut->strs[i] );
                    }
                    pIn->n_strs = pOut->n_strs;
                }
                break;
            case T::U64:
                {
                    for( xos::xos_u8 i = 0; i < pOut->n_u64; ++i )
                    {
                        pIn->u64[i] = pOut->u64[i];
                    }
                    pIn->n_u64 = pOut->n_u64;
                }
                break;
            case T::U32:
                {
                    for( xos::xos_u8 i = 0; i < pOut->n_u32; ++i )
                    {
                        pIn->u32[i] = pOut->u32[i];
                    }
                    pIn->n_u32 = pOut->n_u32;
                }
                break;
            case T::U16:
                {
                    for( xos::xos_u8 i = 0; i < pOut->n_u16; ++i )
                    {
                        pIn->u16[i] = pOut->u16[i];
                    }
                    pIn->n_u16 = pOut->n_u16;
                }
                break;
            case T::U8:
                {
                    for( xos::xos_u8 i = 0; i < pOut->n_u8; ++i )
                    {
                        pIn->u8[i] = pOut->u8[i];
                    }
                    pIn->n_u8 = pOut->n_u8;
                }
                break;
            case T::DOUBLE:
                {
                    for( xos::xos_u8 i = 0; i < pOut->n_d; ++i )
                    {
                        pIn->d[i] = pOut->d[i];
                    }
                    pIn->n_d = pOut->n_d;
                }
                break;
            case T::FLOAT:
                {
                    for( xos::xos_u8 i = 0; i < pOut->n_f; ++i )
                    {
                        pIn->f[i] = pOut->f[i];
                    }
                    pIn->n_f = pOut->n_f;
                }
                break;
            default:
                {
                    ret = 1;
                }
                break;
            }
            return ret;
        }
        //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        // 
        static int push( T * pT )
        {
            int ret = 0;
            T::add_item( pT );
            return ret;
        }
    };

}

#endif // __XOSKIT_XOS_CORE_XOS_STL_SRC_PROTOCOL_PACKER_PROTOCOL_DAT_H__
